cmake_minimum_required(VERSION 3.10)

####################################################################################################
########################################    platform select    #####################################
####################################################################################################
## NOTE: vendor provided platform. !!!This variable MUST be set properly!!!
set(PLATFORM_TYPE           ln882h)

## A flag only meaningful to vendor.
set(VENDOR_SDK_ADAPTED      ON)

## third-party LwIP is enabled, only meaningful to vendor.
set(THIRD_PARTY_LWIP        ON)

if (EXISTS  ${CMAKE_CURRENT_SOURCE_DIR}/platforms/${PLATFORM_TYPE})
    message(STATUS       "platform ${PLATFORM_TYPE} exists")
else()
    message(STATUS "##############################################################################")
    message(STATUS "##  Error: platform ${PLATFORM_TYPE} not found!!!                             ")
    message(STATUS "##  Download platform ${PLATFORM_TYPE} SDK first before doing anything!!!     ")
    message(STATUS "##  Enter cmd line:                                                           ")
    message(STATUS "##           git  submodule  update  --init                                   ")
    message(STATUS "##############################################################################")
    message(FATAL_ERROR  "")
endif()

####################################################################################################
########################################  Debug/Release  ###########################################
####################################################################################################
set(CMAKE_BUILD_TYPE  Release CACHE  STRING  "build for release"    FORCE)
# set(CMAKE_BUILD_TYPE  Debug   CACHE  STRING  "build for debug"      FORCE)

set(allowableBuildTypes  Debug  Release)
if (NOT CMAKE_BUILD_TYPE IN_LIST  allowableBuildTypes)
    set(CMAKE_BUILD_TYPE  Debug   CACHE  STRING  "build for debug"      FORCE)
endif()
message(STATUS  "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")

####################################################################################################
########################################    toolchain setup    #####################################
####################################################################################################
if (DEFINED LN_SDK_ROOT)
    message(STATUS "<GET> LN_SDK_ROOT = ${LN_SDK_ROOT}")
else()
    set(LN_SDK_ROOT     ${CMAKE_CURRENT_SOURCE_DIR}/platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk)
    message(STATUS "<SET> LN_SDK_ROOT = ${LN_SDK_ROOT}")
endif()

if (${PLATFORM_TYPE}  STREQUAL  "ln882h")
    set(CHIP_SERIAL  ${PLATFORM_TYPE})
    include(${LN_SDK_ROOT}/project/main_entry_for_tuya/gcc/gcc-toolchain-setup.cmake)
    include(${LN_SDK_ROOT}/project/main_entry_for_tuya/gcc/gcc-compiler-flags.cmake)
else()
    message(STATUS      "#########################################################################")
    message(STATUS      "##  PLATFORM_TYPE = ${PLATFORM_TYPE}, is invalid. Please check again!!!  ")
    message(STATUS      "#########################################################################")
    message(FATAL_ERROR "##  Check PLATFORM_TYPE = ${PLATFORM_TYPE}")
endif()

####################################################################################################
########################################   cmake settings    #######################################
####################################################################################################
project(LN-TuyaYun
    VERSION  1.0.0
    DESCRIPTION  "LN SDK for TuyaYun"
    LANGUAGES  C  CXX  ASM
)

# show verbose build message.
# set(CMAKE_VERBOSE_MAKEFILE  ON)
# set(CMAKE_VERBOSE_MAKEFILE  OFF)

set(EXECUTABLE_OUTPUT_PATH    ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH       ${CMAKE_BINARY_DIR}/lib)

####################################################################################################
#######################################    tuya App select    ######################################
####################################################################################################

## Select App to be build:
## 1. app resides in `apps/` directory. Only one app can be chosen!!!
## 2. APP_NAME, can be one of "rtlbn_one_plug_demo" or "rtlbn_light_base_local";
## 3. PRODECT_KEY, comes from app configuration file name, such as "product_4b1xceqdkdzdixu5_1.0.0";
## 4. PRODUCT_VER, comes from app configuration file name, such as "product_4b1xceqdkdzdixu5_1.0.0";
## -------------------------------------------------------------------------------------------------

# set(APP_NAME        "rtlbn_one_plug_demo")
# set(PRODECT_KEY     "4b1xceqdkdzdixu5")
# set(PRODUCT_VER     "1.0.0")

# FIXME: to be adapted...
# set(APP_NAME        "rtlbn_light_base_local")
# set(PRODECT_KEY     "5w5ljpr6l2uokbfe")
# set(PRODUCT_VER     "1.0.5")

# FIXME: to be adapted...
set(APP_NAME        "ln882h_one_plug_demo")
set(PRODECT_KEY     "wj34u3zqox4jep7p")
set(PRODUCT_VER     "1.0.0")

# FIXME: to be adapted...
# set(APP_NAME        "tuya_uart_common_demo")
# set(PRODECT_KEY     "u8om0z8xjoazy904")
# set(PRODUCT_VER     "1.0.0")

#################  Global parameter parsed from app config, no manual change is required  ##########
set(APP_PATH                ${CMAKE_CURRENT_SOURCE_DIR}/apps/${APP_NAME})
set(PRODUCT_CFG_FILENAME    product_${PRODECT_KEY}_${PRODUCT_VER})
set(PRODUCT_CFG_FILEPATH    ${APP_PATH}/${PRODUCT_CFG_FILENAME})
set(PRODUCT_CFG_HEADER      ${APP_PATH}/src/.compile_usr_cfg.h)

string(TIMESTAMP COMPILE_TIME %Y-%m-%d_%H:%M:%S)
set(ln_ty_sdk_build_time   ${COMPILE_TIME})

message(STATUS   "current dir: ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS   "ln_ty_sdk build time: ${COMPILE_TIME}")


# get git hash
macro(get_git_hash _git_hash)
    find_package(Git QUIET)
    if(GIT_FOUND)
        execute_process(
            COMMAND git log -1 --pretty=format:%h
            OUTPUT_VARIABLE ${_git_hash}
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
            WORKING_DIRECTORY
            ${CMAKE_CURRENT_SOURCE_DIR}
        )
    endif()
endmacro()

# get git branch
macro(get_git_branch _git_branch)
    find_package(Git QUIET)
    if(GIT_FOUND)
        execute_process(
            COMMAND git symbolic-ref --short -q HEAD
            OUTPUT_VARIABLE ${_git_branch}
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
            WORKING_DIRECTORY
            ${CMAKE_CURRENT_SOURCE_DIR}
        )
    endif()
endmacro()

# git hash
set(SDK_GIT_HASH "")
get_git_hash(SDK_GIT_HASH)
# git branch
set(SDK_GIT_BRANCH "")
get_git_branch(SDK_GIT_BRANCH)

message(STATUS   "git head: ${SDK_GIT_HASH}; git branch: ${SDK_GIT_BRANCH}")

configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/platforms/ln_ty_sdk_version.h.in"
    "${CMAKE_CURRENT_SOURCE_DIR}/platforms/ln_ty_sdk_version.h"
)

function(PARSE_CONFIG_BIN_NAME  file_path  sw_ver bin_name)
    if(NOT  EXISTS  ${file_path})
        message(FATAL_ERROR  "ERROR: user config file does NOT exist!!!")
    endif()

    file(STRINGS  ${file_path}  file_content
            REGEX  "^.*$"
            ENCODING  "UTF-8"
            LIMIT_COUNT  5
    )
    set(result_list  ${file_content})
    list(POP_BACK  result_list  val)
    list(POP_BACK  result_list  val)
    set(${bin_name}  ${val}  PARENT_SCOPE)
    string(LENGTH  ${val}  bin_name_len)
    if (${bin_name_len}  EQUAL  0)
        message(FATAL_ERROR  "ERROR: parse bin name, please check product config file!!!")
    endif()

    list(POP_BACK  result_list  val)
    set(${sw_ver}   ${val}  PARENT_SCOPE)
    string(LENGTH  ${val}  sw_ver_len)
    if (${sw_ver_len}  LESS  5)
        message(FATAL_ERROR  "ERROR: parse sw ver, please check product config file!!!")
    endif()
endfunction()

# src/.compile_usr_cfg.h
function(USR_COMPILE_CFG_PREPARE  src_path  dst_path)
    message(STATUS "prepare: ${dst_path}")
    if(EXISTS  ${src_path})
        file(GENERATE OUTPUT ${dst_path}
                INPUT ${src_path}
        )
    else()
        message(FATAL_ERROR  "ERROR: user config file can not be found: ${src_path}")
    endif()
endfunction()

####################################################################################################
##########################################  main flow  #############################################
####################################################################################################

## 1. Parse config file.
## ----------------------

if(NOT EXISTS  ${APP_PATH})
    message(FATAL_ERROR  "ERROR: Unknown user app: ${APP_NAME}!!!")
endif()

if(EXISTS  ${PRODUCT_CFG_FILEPATH})
    PARSE_CONFIG_BIN_NAME(${PRODUCT_CFG_FILEPATH}  USER_SW_VER APP_BIN_NAME)
    message(STATUS "------>  USER_SW_VER = ${USER_SW_VER}")
    message(STATUS "------>  APP_BIN_NAME = ${APP_BIN_NAME}")

    USR_COMPILE_CFG_PREPARE(${PRODUCT_CFG_FILEPATH}  ${PRODUCT_CFG_HEADER})
else()
    message(FATAL_ERROR  "ERROR: unknown user config: ${PRODUCT_CFG_FILENAME}")
endif()

add_compile_definitions(APP_BIN_NAME=\"${APP_BIN_NAME}\")
add_compile_definitions(USER_SW_VER=\"${USER_SW_VER}\")

## 2. set header file search path.
## -------------------------------
include_directories(platforms)
include_directories(sdk/include)

if (${PLATFORM_TYPE}  STREQUAL  "ln882h")
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/mcu/${PLATFORM_TYPE})
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/mcu/CMSIS_5.3.0)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/mcu/driver_${PLATFORM_TYPE})
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/mcu/driver_${PLATFORM_TYPE}/reg)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/kernel)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/kernel/FreeRTOS/Source/include)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/kernel/FreeRTOS/Source/portable/GCC/ARM_CM4F)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/kernel/FreeRTOS_Adapter)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/net/dhcpd)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/wifi/wifi_lib_export)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/wifi/wifi_lib_import)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/wifi/wifi_manager)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/ble)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/ble/ble_arch)


    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/fota/ota_agent)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/fs/partition_mgr)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/fs/nvds)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/fs/kv/kv)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/fs/kv/kv_port)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/serial)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/components/utils)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/project/main_entry_for_tuya/cfg)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/project/main_entry_for_tuya/bsp)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/project/main_entry_for_tuya/app/ble_usr_app)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/project/main_entry_for_tuya/app/ble_usr_app/app_callback)
    include_directories(platforms/${PLATFORM_TYPE}/${PLATFORM_TYPE}-sdk/project/main_entry_for_tuya/app/)

    include_directories(platforms/${PLATFORM_TYPE}/adapter/lwip-2.1.3/src/include)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/lwip-2.1.3/src/port/ln_osal/include)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_common/include)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_common/include/driver)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_os_adapter/include)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_os_adapter/include/driver)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_os_adapter/include/system)
    include_directories(platforms/${PLATFORM_TYPE}/adapter/tuya_adapter_test/include)
else()
    message(STATUS      "#########################################################################")
    message(STATUS      "##  Put platform header path here!!!                                   ##")
    message(STATUS      "#########################################################################")
endif()

## 3. add app and library
## ----------------------
add_subdirectory(apps)
add_subdirectory(platforms)
